package com.groupbuying.currency.consumer.service.impl;

import com.aliyun.openservices.shade.com.alibaba.rocketmq.common.admin.RollbackStats;
import com.groupbuying.currency.consumer.connector.SysconfigFeign;
import com.groupbuying.currency.consumer.constants.CommonConstants;
import com.groupbuying.currency.consumer.constants.CurrencyConstants;
import com.groupbuying.currency.consumer.context.FilterContextHandler;
import com.groupbuying.currency.consumer.dao.CurrencyCustomerDao;
import com.groupbuying.currency.consumer.dao.CurrencyCustomerLogDao;
import com.groupbuying.currency.consumer.domain.CurrencyCustomerDO;
import com.groupbuying.currency.consumer.domain.CurrencyCustomerLogDO;
import com.groupbuying.currency.consumer.service.CurrencyCustomerService;
import com.groupbuying.currency.consumer.utils.DateUtils;
import com.groupbuying.currency.consumer.utils.MD5Utils;
import com.groupbuying.currency.consumer.utils.apiresult.ApiResult;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;


@Service
public class CurrencyCustomerServiceImpl implements CurrencyCustomerService {

  @Autowired
  private CurrencyCustomerDao currencyCustomerDao;

  @Autowired
  private CurrencyCustomerLogDao currencyCustomerLogDao;

  @Autowired
  private SysconfigFeign sysconfigFeign;

  @Override
  public CurrencyCustomerDO get(String customerId) {
    return currencyCustomerDao.get(customerId);
  }

  @Override
  public List<CurrencyCustomerDO> list(Map<String, Object> map) {
    return currencyCustomerDao.list(map);
  }

  @Override
  public int count(Map<String, Object> map) {
    return currencyCustomerDao.count(map);
  }

  @Override
  public int save(CurrencyCustomerDO currencyCustomer) {
    return currencyCustomerDao.save(currencyCustomer);
  }

  @Override
  public int update(CurrencyCustomerDO currencyCustomer) {
    return currencyCustomerDao.update(currencyCustomer);
  }

  @Override
  public int remove(String customerId) {
    return currencyCustomerDao.remove(customerId);
  }

  @Override
  public int batchRemove(String[] customerIds) {
    return currencyCustomerDao.batchRemove(customerIds);
  }

  /**
   * Description 通过线上非积分消费，增加账户积分 <br>
   *
   * @param customerId - 积分账户Id
   * @param payId - 支付Id
   * @param consumptionAmount - 消费金额
   * @param backCurrencyRatio - 返积分率
   * @return 返回更新后的对象
   * @author Ywxd <br>
   * @createDate 2019/5/20 15:48<br>
   **/
  @Override
  @Transactional(rollbackFor = Exception.class)
  public CurrencyCustomerDO addCurrencyByOnlineConsumption(String customerId, String payId
      , BigDecimal consumptionAmount, BigDecimal backCurrencyRatio) {

    /* 0. 传入参数校验 */
    if (consumptionAmount == null || backCurrencyRatio == null
        || consumptionAmount.compareTo(new BigDecimal(0)) == 0
        || backCurrencyRatio.compareTo(new BigDecimal(0)) == 0) {
      try {
        throw new Exception("addCurrencyByOnlineConsumption 传入参数不合法！");
      } catch (Exception e) {
        e.printStackTrace();
      }
    }

    /* 1. 根据customerId获取积分账户对象及相关积分数额 */
    CurrencyCustomerDO currencyCustomerDO = currencyCustomerDao.get(customerId);
    BigDecimal useCurrency = currencyCustomerDO.getUseCurrency();
    BigDecimal totalCurrency = currencyCustomerDO.getTotalCurrency();

    /* 2. 计算消费返的积分 */
    BigDecimal addedCurrency = consumptionAmount.multiply(backCurrencyRatio)
        .divide(new BigDecimal("100")).setScale(2, BigDecimal.ROUND_DOWN);


    /* 3. 重新装配对象，并更新数据库，返回更新后的对象 */
    currencyCustomerDO.setUseCurrency(useCurrency.add(addedCurrency));
    currencyCustomerDO.setTotalCurrency(currencyCustomerDO.getUseCurrency().add(currencyCustomerDO.getFreezeCurrency()));
    int returnValue = currencyCustomerDao.update(currencyCustomerDO);

    /* 4. 同步增加积分日志记录 */
    if (returnValue > 0) {

      /* 日志数据装配并储入库表 */
      CurrencyCustomerLogDO currencyCustomerLogDO = new CurrencyCustomerLogDO();

      currencyCustomerLogDO.setActivityId(null);
      currencyCustomerLogDO.setLogId(sysconfigFeign.createLogID());
      currencyCustomerLogDO.setDelFlag(CommonConstants.COMMON_FLAG_UNDEL);
      currencyCustomerLogDO.setCreateTime(DateUtils.format(new Date(), DateUtils.YMDHMS));
      currencyCustomerLogDO.setPayId(payId);
      currencyCustomerLogDO.setCustomerId(customerId);
      /* 碎银流向：01、活动；02、消费 */
      currencyCustomerLogDO.setCurrencySource(CurrencyConstants.CURRENCY_SOURCE_CONSUME);
      /* 碎银变化类型：01：增加：02减少，03：无变化 */
      currencyCustomerLogDO.setCurrencyType(CurrencyConstants.CURRENCY_TYPE_INCREASE);
      currencyCustomerLogDO.setCurrencyCount(addedCurrency);
      currencyCustomerLogDO.setCurrencyBalance(currencyCustomerDO.getTotalCurrency());
      currencyCustomerLogDao.save(currencyCustomerLogDO);

    }

    return currencyCustomerDO;
  }

  /**
   * Description 创建积分账户 <br>
   * 异步创建, 未启用
   * @return CurrencyCustomerDO
   * @author Ywxd <br>
   * @createDate 2019/4/15 17:41<br>
   **/
  @Transactional(rollbackFor = Exception.class)
  @Override
  public CurrencyCustomerDO createCurrencyCustomer(String customerID) {

    /* 创建积分账户逻辑 */
    /* 1、新建积分账户空对象等待填入 */
    CurrencyCustomerDO currencyCustomerDO = new CurrencyCustomerDO();

    /* 2、装配积分账户数据并存入库表 */
    currencyCustomerDO.setCustomerId(customerID);
    currencyCustomerDO.setCreateTime(DateUtils.format(new Date(), DateUtils.YMDHMS));
    currencyCustomerDO.setDelFlag(CommonConstants.COMMON_FLAG_UNDEL);

    /* 创建积分用户时候先不赠送积分，之后再处理积分逻辑 */
    currencyCustomerDO.setUseCurrency(new BigDecimal(0));
    currencyCustomerDO.setFreezeCurrency(new BigDecimal(0));
    currencyCustomerDO.setTotalCurrency(new BigDecimal(0));
    int returnValue = currencyCustomerDao.save(currencyCustomerDO);

    /* 3、积分中心日志记录，需要和积分账户创建成为事务 */
    if (returnValue > 0) {
      /* 日志数据装配并储入库表 */
      CurrencyCustomerLogDO currencyCustomerLogDO = new CurrencyCustomerLogDO();

      /* 创建积分用户的时候先设置ActivityID先为空 */
      currencyCustomerLogDO.setActivityId(null);
      currencyCustomerLogDO.setLogId(sysconfigFeign.createLogID());
      currencyCustomerLogDO.setDelFlag(CommonConstants.COMMON_FLAG_UNDEL);
      currencyCustomerLogDO.setCreateTime(DateUtils.format(new Date(), DateUtils.YMDHMS));
      currencyCustomerLogDO.setCustomerId(customerID);
      /* 碎银流向：01、活动；02、消费 */
      currencyCustomerLogDO.setCurrencySource(CurrencyConstants.CURRENCY_SOURCE_ACTIVITY);
      /* 碎银变化类型：01：增加：02减少，03：无变化 */
      currencyCustomerLogDO.setCurrencyType(CurrencyConstants.CURRENCY_TYPE_UNCHANGED);
      currencyCustomerLogDO.setCurrencyCount(new BigDecimal(0));
      currencyCustomerLogDO.setCurrencyBalance(currencyCustomerDO.getTotalCurrency());
      currencyCustomerLogDao.save(currencyCustomerLogDO);
    }

    return currencyCustomerDO;
  }

  /**
   * Description 修改积分支付密码 <br>
   *
   * @return 更改积分支付密码的结果
   * @author Ywxd <br>
   * @createDate 2019/5/20 15:35<br>
   **/
  @Override
  public ApiResult changeCurrencyPwd(Map<String, Object> mapParams) {
    Object tempParam = mapParams.get("password");
    String password = tempParam == null ? null : tempParam.toString();

    //判断请求参数不为空
    if (StringUtils.isEmpty(password)) {
      return ApiResult.paramIsNull();
    }

    String customerUuid = FilterContextHandler.getUserID();
    CurrencyCustomerDO currencyCustomerDO = new CurrencyCustomerDO();
    currencyCustomerDO.setCustomerId(customerUuid);
    currencyCustomerDO.setPassword(MD5Utils.encrypt(customerUuid, password));
    this.update(currencyCustomerDO);

    return ApiResult.operateSuccess();
  }

  /**
   * Description 校验积分支付密码 <br>
   *
   * @param customerId - 积分账户ID
   * @param password - 积分支付密码
   * @return 积分支付密码是否正确
   * @author Ywxd <br>
   * @createDate 2019/5/20 15:36<br>
   **/
  @Override
  public Boolean checkCurrencyPwd(String customerId, String password) {
    CurrencyCustomerDO currencyCustomerDO = currencyCustomerDao.get(customerId);
    String password_new = MD5Utils.encrypt(customerId, password);
    if (currencyCustomerDO.getPassword().equals(password_new)) {
      return true;
    } else {
      return false;
    }
  }

}
